home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / ruby / 1.8 / erb.rb < prev    next >
Text File  |  2008-07-10  |  23KB  |  897 lines

  1. # = ERB -- Ruby Templating
  2. #
  3. # Author:: Masatoshi SEKI
  4. # Documentation:: James Edward Gray II and Gavin Sinclair
  5. #
  6. # See ERB for primary documentation and ERB::Util for a couple of utility
  7. # routines.
  8. #
  9. # Copyright (c) 1999-2000,2002,2003 Masatoshi SEKI
  10. #
  11. # You can redistribute it and/or modify it under the same terms as Ruby.
  12.  
  13. #
  14. # = ERB -- Ruby Templating
  15. #
  16. # == Introduction
  17. #
  18. # ERB provides an easy to use but powerful templating system for Ruby.  Using
  19. # ERB, actual Ruby code can be added to any plain text document for the
  20. # purposes of generating document information details and/or flow control.
  21. #
  22. # A very simple example is this:
  23. #   require 'erb'
  24. #
  25. #   x = 42
  26. #   template = ERB.new <<-EOF
  27. #     The value of x is: <%= x %>
  28. #   EOF
  29. #   puts template.result(binding)
  30. #
  31. # <em>Prints:</em> The value of x is: 42
  32. #
  33. # More complex examples are given below.
  34. #
  35. #
  36. # == Recognized Tags
  37. #
  38. # ERB recognizes certain tags in the provided template and converts them based
  39. # on the rules below:
  40. #
  41. #   <% Ruby code -- inline with output %>
  42. #   <%= Ruby expression -- replace with result %>
  43. #   <%# comment -- ignored -- useful in testing %>
  44. #   % a line of Ruby code -- treated as <% line %> (optional -- see ERB.new)
  45. #   %% replaced with % if first thing on a line and % processing is used
  46. #   <%% or %%> -- replace with <% or %> respectively
  47. #
  48. # All other text is passed through ERB filtering unchanged.
  49. #
  50. #
  51. # == Options
  52. #
  53. # There are several settings you can change when you use ERB:
  54. # * the nature of the tags that are recognized;
  55. # * the value of <tt>$SAFE</tt> under which the template is run;
  56. # * the binding used to resolve local variables in the template.
  57. #
  58. # See the ERB.new and ERB#result methods for more detail.
  59. #
  60. #
  61. # == Examples
  62. #
  63. # === Plain Text
  64. #
  65. # ERB is useful for any generic templating situation.  Note that in this example, we use the
  66. # convenient "% at start of line" tag, and we quote the template literally with
  67. # <tt>%q{...}</tt> to avoid trouble with the backslash.
  68. #
  69. #   require "erb"
  70. #   
  71. #   # Create template.
  72. #   template = %q{
  73. #     From:  James Edward Gray II <james@grayproductions.net>
  74. #     To:  <%= to %>
  75. #     Subject:  Addressing Needs
  76. #   
  77. #     <%= to[/\w+/] %>:
  78. #   
  79. #     Just wanted to send a quick note assuring that your needs are being
  80. #     addressed.
  81. #   
  82. #     I want you to know that my team will keep working on the issues,
  83. #     especially:
  84. #   
  85. #     <%# ignore numerous minor requests -- focus on priorities %>
  86. #     % priorities.each do |priority|
  87. #       * <%= priority %>
  88. #     % end
  89. #   
  90. #     Thanks for your patience.
  91. #   
  92. #     James Edward Gray II
  93. #   }.gsub(/^  /, '')
  94. #   
  95. #   message = ERB.new(template, 0, "%<>")
  96. #   
  97. #   # Set up template data.
  98. #   to = "Community Spokesman <spokesman@ruby_community.org>"
  99. #   priorities = [ "Run Ruby Quiz",
  100. #                  "Document Modules",
  101. #                  "Answer Questions on Ruby Talk" ]
  102. #   
  103. #   # Produce result.
  104. #   email = message.result
  105. #   puts email
  106. #
  107. # <i>Generates:</i>
  108. #
  109. #   From:  James Edward Gray II <james@grayproductions.net>
  110. #   To:  Community Spokesman <spokesman@ruby_community.org>
  111. #   Subject:  Addressing Needs
  112. #   
  113. #   Community:
  114. #   
  115. #   Just wanted to send a quick note assuring that your needs are being addressed.
  116. #   
  117. #   I want you to know that my team will keep working on the issues, especially:
  118. #   
  119. #       * Run Ruby Quiz
  120. #       * Document Modules
  121. #       * Answer Questions on Ruby Talk
  122. #   
  123. #   Thanks for your patience.
  124. #   
  125. #   James Edward Gray II
  126. #
  127. # === Ruby in HTML
  128. #
  129. # ERB is often used in <tt>.rhtml</tt> files (HTML with embedded Ruby).  Notice the need in
  130. # this example to provide a special binding when the template is run, so that the instance
  131. # variables in the Product object can be resolved.
  132. #
  133. #   require "erb"
  134. #   
  135. #   # Build template data class.
  136. #   class Product
  137. #     def initialize( code, name, desc, cost )
  138. #       @code = code
  139. #       @name = name
  140. #       @desc = desc
  141. #       @cost = cost
  142. #            
  143. #       @features = [ ]
  144. #     end
  145. #   
  146. #     def add_feature( feature )
  147. #       @features << feature
  148. #     end
  149. #   
  150. #     # Support templating of member data.
  151. #     def get_binding
  152. #       binding
  153. #     end
  154. #   
  155. #     # ...
  156. #   end
  157. #   
  158. #   # Create template.
  159. #   template = %{
  160. #     <html>
  161. #       <head><title>Ruby Toys -- <%= @name %></title></head>
  162. #       <body>
  163. #   
  164. #         <h1><%= @name %> (<%= @code %>)</h1>
  165. #         <p><%= @desc %></p>
  166. #   
  167. #         <ul>
  168. #           <% @features.each do |f| %>
  169. #             <li><b><%= f %></b></li>
  170. #           <% end %>
  171. #         </ul>
  172. #   
  173. #         <p>
  174. #           <% if @cost < 10 %>
  175. #             <b>Only <%= @cost %>!!!</b>
  176. #           <% else %>
  177. #              Call for a price, today!
  178. #           <% end %>
  179. #         </p>
  180. #    
  181. #       </body>
  182. #     </html>
  183. #   }.gsub(/^  /, '')
  184. #   
  185. #   rhtml = ERB.new(template)
  186. #   
  187. #   # Set up template data.
  188. #   toy = Product.new( "TZ-1002",
  189. #                      "Rubysapien",
  190. #                      "Geek's Best Friend!  Responds to Ruby commands...",
  191. #                      999.95 )
  192. #   toy.add_feature("Listens for verbal commands in the Ruby language!")
  193. #   toy.add_feature("Ignores Perl, Java, and all C variants.")
  194. #   toy.add_feature("Karate-Chop Action!!!")
  195. #   toy.add_feature("Matz signature on left leg.")
  196. #   toy.add_feature("Gem studded eyes... Rubies, of course!")
  197. #   
  198. #   # Produce result.
  199. #   rhtml.run(toy.get_binding)
  200. #
  201. # <i>Generates (some blank lines removed):</i>
  202. #
  203. #    <html>
  204. #      <head><title>Ruby Toys -- Rubysapien</title></head>
  205. #      <body>
  206. #    
  207. #        <h1>Rubysapien (TZ-1002)</h1>
  208. #        <p>Geek's Best Friend!  Responds to Ruby commands...</p>
  209. #    
  210. #        <ul>
  211. #            <li><b>Listens for verbal commands in the Ruby language!</b></li>
  212. #            <li><b>Ignores Perl, Java, and all C variants.</b></li>
  213. #            <li><b>Karate-Chop Action!!!</b></li>
  214. #            <li><b>Matz signature on left leg.</b></li>
  215. #            <li><b>Gem studded eyes... Rubies, of course!</b></li>
  216. #        </ul>
  217. #    
  218. #        <p>
  219. #             Call for a price, today!
  220. #        </p>
  221. #    
  222. #      </body>
  223. #    </html>
  224. #
  225. # == Notes
  226. #
  227. # There are a variety of templating solutions available in various Ruby projects:
  228. # * ERB's big brother, eRuby, works the same but is written in C for speed;
  229. # * Amrita (smart at producing HTML/XML);
  230. # * cs/Template (written in C for speed);
  231. # * RDoc, distributed with Ruby, uses its own template engine, which can be reused elsewhere;
  232. # * and others; search the RAA.
  233. #
  234. # Rails, the web application framework, uses ERB to create views.
  235. #
  236. class ERB
  237.   Revision = '$Date: 2008-07-10 18:43:07 +0900 (Thu, 10 Jul 2008) $'     #'
  238.  
  239.   # Returns revision information for the erb.rb module.
  240.   def self.version
  241.     "erb.rb [2.1.0 #{ERB::Revision.split[1]}]"
  242.   end
  243. end
  244.  
  245. #--
  246. # ERB::Compiler
  247. class ERB
  248.   class Compiler # :nodoc:
  249.     class PercentLine # :nodoc:
  250.       def initialize(str)
  251.         @value = str
  252.       end
  253.       attr_reader :value
  254.       alias :to_s :value
  255.  
  256.       def empty?
  257.         @value.empty?
  258.       end
  259.     end
  260.  
  261.     class Scanner # :nodoc:
  262.       @scanner_map = {}
  263.       def self.regist_scanner(klass, trim_mode, percent)
  264.     @scanner_map[[trim_mode, percent]] = klass
  265.       end
  266.  
  267.       def self.default_scanner=(klass)
  268.     @default_scanner = klass
  269.       end
  270.  
  271.       def self.make_scanner(src, trim_mode, percent)
  272.     klass = @scanner_map.fetch([trim_mode, percent], @default_scanner)
  273.     klass.new(src, trim_mode, percent)
  274.       end
  275.  
  276.       def initialize(src, trim_mode, percent)
  277.     @src = src
  278.     @stag = nil
  279.       end
  280.       attr_accessor :stag
  281.  
  282.       def scan; end
  283.     end
  284.  
  285.     class TrimScanner < Scanner # :nodoc:
  286.       def initialize(src, trim_mode, percent)
  287.     super
  288.     @trim_mode = trim_mode
  289.     @percent = percent
  290.     if @trim_mode == '>'
  291.       @scan_line = self.method(:trim_line1)
  292.     elsif @trim_mode == '<>'
  293.       @scan_line = self.method(:trim_line2)
  294.     elsif @trim_mode == '-'
  295.       @scan_line = self.method(:explicit_trim_line)
  296.     else
  297.       @scan_line = self.method(:scan_line)
  298.     end
  299.       end
  300.       attr_accessor :stag
  301.       
  302.       def scan(&block)
  303.     @stag = nil
  304.     if @percent
  305.       @src.each do |line|
  306.         percent_line(line, &block)
  307.       end
  308.     else
  309.           @scan_line.call(@src, &block)
  310.     end
  311.     nil
  312.       end
  313.  
  314.       def percent_line(line, &block)
  315.     if @stag || line[0] != ?%
  316.       return @scan_line.call(line, &block)
  317.     end
  318.  
  319.     line[0] = ''
  320.     if line[0] == ?%
  321.       @scan_line.call(line, &block)
  322.     else
  323.           yield(PercentLine.new(line.chomp))
  324.     end
  325.       end
  326.  
  327.       def scan_line(line)
  328.         line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
  329.           tokens.each do |token|
  330.             next if token.empty?
  331.             yield(token)
  332.           end
  333.     end
  334.       end
  335.  
  336.       def trim_line1(line)
  337.         line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
  338.           tokens.each do |token|
  339.             next if token.empty?
  340.             if token == "%>\n"
  341.               yield('%>')
  342.               yield(:cr)
  343.             else
  344.               yield(token)
  345.             end
  346.           end
  347.     end
  348.       end
  349.  
  350.       def trim_line2(line)
  351.     head = nil
  352.         line.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
  353.           tokens.each do |token|
  354.             next if token.empty?
  355.             head = token unless head
  356.             if token == "%>\n"
  357.               yield('%>')
  358.               if is_erb_stag?(head)
  359.                 yield(:cr)
  360.               else
  361.                 yield("\n")
  362.               end
  363.               head = nil
  364.             else
  365.               yield(token)
  366.               head = nil if token == "\n"
  367.             end
  368.           end
  369.     end
  370.       end
  371.  
  372.       def explicit_trim_line(line)
  373.         line.scan(/(.*?)(^[ \t]*<%\-|<%\-|<%%|%%>|<%=|<%#|<%|-%>\n|-%>|%>|\z)/m) do |tokens|
  374.           tokens.each do |token|
  375.             next if token.empty?
  376.             if @stag.nil? && /[ \t]*<%-/ =~ token
  377.               yield('<%')
  378.             elsif @stag && token == "-%>\n"
  379.               yield('%>')
  380.               yield(:cr)
  381.             elsif @stag && token == '-%>'
  382.               yield('%>')
  383.             else
  384.               yield(token)
  385.             end
  386.           end
  387.         end
  388.       end
  389.  
  390.       ERB_STAG = %w(<%= <%# <%)
  391.       def is_erb_stag?(s)
  392.     ERB_STAG.member?(s)
  393.       end
  394.     end
  395.  
  396.     Scanner.default_scanner = TrimScanner
  397.  
  398.     class SimpleScanner < Scanner # :nodoc:
  399.       def scan
  400.         @src.scan(/(.*?)(<%%|%%>|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
  401.           tokens.each do |token|
  402.             next if token.empty?
  403.             yield(token)
  404.           end
  405.     end
  406.       end
  407.     end
  408.     
  409.     Scanner.regist_scanner(SimpleScanner, nil, false)
  410.  
  411.     begin
  412.       require 'strscan'
  413.       class SimpleScanner2 < Scanner # :nodoc:
  414.         def scan
  415.           stag_reg = /(.*?)(<%%|<%=|<%#|<%|\z)/m
  416.           etag_reg = /(.*?)(%%>|%>|\z)/m
  417.           scanner = StringScanner.new(@src)
  418.           while ! scanner.eos?
  419.             scanner.scan(@stag ? etag_reg : stag_reg)
  420.             yield(scanner[1])
  421.             yield(scanner[2])
  422.           end
  423.         end
  424.       end
  425.       Scanner.regist_scanner(SimpleScanner2, nil, false)
  426.  
  427.       class PercentScanner < Scanner # :nodoc:
  428.     def scan(&blk)
  429.           stag_reg = /(.*?)(^%%|^%|<%%|<%=|<%#|<%|\z)/m
  430.           etag_reg = /(.*?)(%%>|%>|\z)/m
  431.           scanner = StringScanner.new(@src)
  432.           while ! scanner.eos?
  433.         scanner.scan(@stag ? etag_reg : stag_reg)
  434.             yield(scanner[1])
  435.  
  436.             elem = scanner[2]
  437.             if elem == '%%'
  438.               yield('%')
  439.               inline_scan(scanner.scan(/.*?(\n|\z)/), &blk)
  440.             elsif elem == '%'
  441.               yield(PercentLine.new(scanner.scan(/.*?(\n|\z)/).chomp))
  442.             else
  443.               yield(elem)
  444.             end
  445.           end
  446.         end
  447.  
  448.         def inline_scan(line)
  449.           stag_reg = /(.*?)(<%%|<%=|<%#|<%|\z)/m
  450.           etag_reg = /(.*?)(%%>|%>|\z)/m
  451.           scanner = StringScanner.new(line)
  452.           while ! scanner.eos?
  453.             scanner.scan(@stag ? etag_reg : stag_reg)
  454.             yield(scanner[1])
  455.             yield(scanner[2])
  456.           end
  457.         end
  458.       end
  459.       Scanner.regist_scanner(PercentScanner, nil, true)
  460.  
  461.       class ExplicitScanner < Scanner # :nodoc:
  462.     def scan
  463.           stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%=|<%#|<%-|<%|\z)/m
  464.           etag_reg = /(.*?)(%%>|-%>|%>|\z)/m
  465.           scanner = StringScanner.new(@src)
  466.           while ! scanner.eos?
  467.         scanner.scan(@stag ? etag_reg : stag_reg)
  468.             yield(scanner[1])
  469.  
  470.             elem = scanner[2]
  471.             if /[ \t]*<%-/ =~ elem
  472.               yield('<%')
  473.             elsif elem == '-%>'
  474.           yield('%>')
  475.           yield(:cr) if scanner.scan(/(\n|\z)/)
  476.         else
  477.           yield(elem)
  478.         end
  479.           end
  480.         end
  481.       end
  482.       Scanner.regist_scanner(ExplicitScanner, '-', false)
  483.  
  484.     rescue LoadError
  485.     end
  486.  
  487.     class Buffer # :nodoc:
  488.       def initialize(compiler)
  489.     @compiler = compiler
  490.     @line = []
  491.     @script = ""
  492.     @compiler.pre_cmd.each do |x|
  493.       push(x)
  494.     end
  495.       end
  496.       attr_reader :script
  497.  
  498.       def push(cmd)
  499.     @line << cmd
  500.       end
  501.       
  502.       def cr
  503.     @script << (@line.join('; '))
  504.     @line = []
  505.     @script << "\n"
  506.       end
  507.       
  508.       def close
  509.     return unless @line
  510.     @compiler.post_cmd.each do |x|
  511.       push(x)
  512.     end
  513.     @script << (@line.join('; '))
  514.     @line = nil
  515.       end
  516.     end
  517.  
  518.     def content_dump(s)
  519.       n = s.count("\n")
  520.       if n > 0
  521.         s.dump + "\n" * n
  522.       else
  523.         s.dump
  524.       end
  525.     end
  526.  
  527.     def compile(s)
  528.       out = Buffer.new(self)
  529.  
  530.       content = ''
  531.       scanner = make_scanner(s)
  532.       scanner.scan do |token|
  533.         next if token.nil? 
  534.         next if token == ''
  535.     if scanner.stag.nil?
  536.       case token
  537.           when PercentLine
  538.         out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
  539.         content = ''
  540.             out.push(token.to_s)
  541.             out.cr
  542.       when :cr
  543.         out.cr
  544.       when '<%', '<%=', '<%#'
  545.         scanner.stag = token
  546.         out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
  547.         content = ''
  548.       when "\n"
  549.         content << "\n"
  550.         out.push("#{@put_cmd} #{content_dump(content)}")
  551.         content = ''
  552.       when '<%%'
  553.         content << '<%'
  554.       else
  555.         content << token
  556.       end
  557.     else
  558.       case token
  559.       when '%>'
  560.         case scanner.stag
  561.         when '<%'
  562.           if content[-1] == ?\n
  563.         content.chop!
  564.         out.push(content)
  565.         out.cr
  566.           else
  567.         out.push(content)
  568.           end
  569.         when '<%='
  570.           out.push("#{@insert_cmd}((#{content}).to_s)")
  571.         when '<%#'
  572.           # out.push("# #{content_dump(content)}")
  573.         end
  574.         scanner.stag = nil
  575.         content = ''
  576.       when '%%>'
  577.         content << '%>'
  578.       else
  579.         content << token
  580.       end
  581.     end
  582.       end
  583.       out.push("#{@put_cmd} #{content_dump(content)}") if content.size > 0
  584.       out.close
  585.       out.script
  586.     end
  587.  
  588.     def prepare_trim_mode(mode)
  589.       case mode
  590.       when 1
  591.     return [false, '>']
  592.       when 2
  593.     return [false, '<>']
  594.       when 0
  595.     return [false, nil]
  596.       when String
  597.     perc = mode.include?('%')
  598.     if mode.include?('-')
  599.       return [perc, '-']
  600.     elsif mode.include?('<>')
  601.       return [perc, '<>']
  602.     elsif mode.include?('>')
  603.       return [perc, '>']
  604.     else
  605.       [perc, nil]
  606.     end
  607.       else
  608.     return [false, nil]
  609.       end
  610.     end
  611.  
  612.     def make_scanner(src)
  613.       Scanner.make_scanner(src, @trim_mode, @percent)
  614.     end
  615.  
  616.     def initialize(trim_mode)
  617.       @percent, @trim_mode = prepare_trim_mode(trim_mode)
  618.       @put_cmd = 'print'
  619.       @insert_cmd = @put_cmd
  620.       @pre_cmd = []
  621.       @post_cmd = []
  622.     end
  623.     attr_reader :percent, :trim_mode
  624.     attr_accessor :put_cmd, :insert_cmd, :pre_cmd, :post_cmd
  625.   end
  626. end
  627.  
  628. #--
  629. # ERB
  630. class ERB
  631.   #
  632.   # Constructs a new ERB object with the template specified in _str_.
  633.   # 
  634.   # An ERB object works by building a chunk of Ruby code that will output
  635.   # the completed template when run. If _safe_level_ is set to a non-nil value,
  636.   # ERB code will be run in a separate thread with <b>$SAFE</b> set to the
  637.   # provided level.
  638.   # 
  639.   # If _trim_mode_ is passed a String containing one or more of the following
  640.   # modifiers, ERB will adjust its code generation as listed:
  641.   # 
  642.   #     %  enables Ruby code processing for lines beginning with %
  643.   #     <> omit newline for lines starting with <% and ending in %>
  644.   #     >  omit newline for lines ending in %>
  645.   # 
  646.   # _eoutvar_ can be used to set the name of the variable ERB will build up
  647.   # its output in.  This is useful when you need to run multiple ERB
  648.   # templates through the same binding and/or when you want to control where
  649.   # output ends up.  Pass the name of the variable to be used inside a String.
  650.   #
  651.   # === Example
  652.   #
  653.   #  require "erb"
  654.   #  
  655.   #  # build data class
  656.   #  class Listings
  657.   #    PRODUCT = { :name => "Chicken Fried Steak",
  658.   #                :desc => "A well messages pattie, breaded and fried.",
  659.   #                :cost => 9.95 }
  660.   #  
  661.   #    attr_reader :product, :price
  662.   #    
  663.   #    def initialize( product = "", price = "" )
  664.   #      @product = product
  665.   #      @price = price
  666.   #    end
  667.   #    
  668.   #    def build
  669.   #      b = binding
  670.   #      # create and run templates, filling member data variables
  671.   #      ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), 0, "", "@product").result b
  672.   #        <%= PRODUCT[:name] %>
  673.   #        <%= PRODUCT[:desc] %>
  674.   #      END_PRODUCT
  675.   #      ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), 0, "", "@price").result b
  676.   #        <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
  677.   #        <%= PRODUCT[:desc] %>
  678.   #      END_PRICE
  679.   #    end
  680.   #  end
  681.   #  
  682.   #  # setup template data
  683.   #  listings = Listings.new
  684.   #  listings.build
  685.   #  
  686.   #  puts listings.product + "\n" + listings.price
  687.   #
  688.   # _Generates_
  689.   #
  690.   #  Chicken Fried Steak
  691.   #  A well messages pattie, breaded and fried.
  692.   #  
  693.   #  Chicken Fried Steak -- 9.95
  694.   #  A well messages pattie, breaded and fried.
  695.   #  
  696.   def initialize(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')
  697.     @safe_level = safe_level
  698.     compiler = ERB::Compiler.new(trim_mode)
  699.     set_eoutvar(compiler, eoutvar)
  700.     @src = compiler.compile(str)
  701.     @filename = nil
  702.   end
  703.  
  704.   # The Ruby code generated by ERB
  705.   attr_reader :src
  706.  
  707.   # The optional _filename_ argument passed to Kernel#eval when the ERB code
  708.   # is run
  709.   attr_accessor :filename
  710.  
  711.   #
  712.   # Can be used to set _eoutvar_ as described in ERB#new.  It's probably easier
  713.   # to just use the constructor though, since calling this method requires the
  714.   # setup of an ERB _compiler_ object.
  715.   #
  716.   def set_eoutvar(compiler, eoutvar = '_erbout')
  717.     compiler.put_cmd = "#{eoutvar}.concat"
  718.     compiler.insert_cmd = "#{eoutvar}.concat"
  719.  
  720.     cmd = []
  721.     cmd.push "#{eoutvar} = ''"
  722.     
  723.     compiler.pre_cmd = cmd
  724.  
  725.     cmd = []
  726.     cmd.push(eoutvar)
  727.  
  728.     compiler.post_cmd = cmd
  729.   end
  730.  
  731.   # Generate results and print them. (see ERB#result)
  732.   def run(b=TOPLEVEL_BINDING)
  733.     print self.result(b)
  734.   end
  735.  
  736.   #
  737.   # Executes the generated ERB code to produce a completed template, returning
  738.   # the results of that code.  (See ERB#new for details on how this process can
  739.   # be affected by _safe_level_.)
  740.   # 
  741.   # _b_ accepts a Binding or Proc object which is used to set the context of
  742.   # code evaluation.
  743.   #
  744.   def result(b=TOPLEVEL_BINDING)
  745.     if @safe_level
  746.       proc { 
  747.     $SAFE = @safe_level
  748.     eval(@src, b, (@filename || '(erb)'), 1)
  749.       }.call
  750.     else
  751.       eval(@src, b, (@filename || '(erb)'), 1)
  752.     end
  753.   end
  754.  
  755.   # Define _methodname_ as instance method of _mod_ from compiled ruby source.
  756.   #
  757.   # example:
  758.   #   filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml
  759.   #   erb = ERB.new(File.read(filename))
  760.   #   erb.def_method(MyClass, 'render(arg1, arg2)', filename)
  761.   #   print MyClass.new.render('foo', 123)
  762.   def def_method(mod, methodname, fname='(ERB)')
  763.     mod.module_eval("def #{methodname}\n" + self.src + "\nend\n", fname, 0)
  764.   end
  765.  
  766.   # Create unnamed module, define _methodname_ as instance method of it, and return it.
  767.   #
  768.   # example:
  769.   #   filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml
  770.   #   erb = ERB.new(File.read(filename))
  771.   #   erb.filename = filename
  772.   #   MyModule = erb.def_module('render(arg1, arg2)')
  773.   #   class MyClass
  774.   #     include MyModule
  775.   #   end
  776.   def def_module(methodname='erb')
  777.     mod = Module.new
  778.     def_method(mod, methodname, @filename || '(ERB)')
  779.     mod
  780.   end
  781.  
  782.   # Define unnamed class which has _methodname_ as instance method, and return it.
  783.   #
  784.   # example:
  785.   #   class MyClass_
  786.   #     def initialize(arg1, arg2)
  787.   #       @arg1 = arg1;  @arg2 = arg2
  788.   #     end
  789.   #   end
  790.   #   filename = 'example.rhtml'  # @arg1 and @arg2 are used in example.rhtml
  791.   #   erb = ERB.new(File.read(filename))
  792.   #   erb.filename = filename
  793.   #   MyClass = erb.def_class(MyClass_, 'render()')
  794.   #   print MyClass.new('foo', 123).render()
  795.   def def_class(superklass=Object, methodname='result')
  796.     cls = Class.new(superklass)
  797.     def_method(cls, methodname, @filename || '(ERB)')
  798.     cls
  799.   end
  800. end
  801.  
  802. #--
  803. # ERB::Util
  804. class ERB
  805.   # A utility module for conversion routines, often handy in HTML generation.
  806.   module Util
  807.     public
  808.     #
  809.     # A utility method for escaping HTML tag characters in _s_.
  810.     # 
  811.     #     require "erb"
  812.     #     include ERB::Util
  813.     #     
  814.     #     puts html_escape("is a > 0 & a < 10?")
  815.     # 
  816.     # _Generates_
  817.     # 
  818.     #     is a > 0 & a < 10?
  819.     #
  820.     def html_escape(s)
  821.       s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<")
  822.     end
  823.     alias h html_escape
  824.     module_function :h
  825.     module_function :html_escape
  826.     
  827.     #
  828.     # A utility method for encoding the String _s_ as a URL.
  829.     # 
  830.     #     require "erb"
  831.     #     include ERB::Util
  832.     #     
  833.     #     puts url_encode("Programming Ruby:  The Pragmatic Programmer's Guide")
  834.     # 
  835.     # _Generates_
  836.     # 
  837.     #     Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
  838.     #
  839.     def url_encode(s)
  840.       s.to_s.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
  841.     end
  842.     alias u url_encode
  843.     module_function :u
  844.     module_function :url_encode
  845.   end
  846. end
  847.  
  848. #--
  849. # ERB::DefMethod
  850. class ERB
  851.   # Utility module to define eRuby script as instance method.
  852.   #
  853.   # === Example
  854.   #
  855.   # example.rhtml:
  856.   #   <% for item in @items %>
  857.   #   <b><%= item %></b>
  858.   #   <% end %>
  859.   #
  860.   # example.rb:
  861.   #   require 'erb'
  862.   #   class MyClass
  863.   #     extend ERB::DefMethod
  864.   #     def_erb_method('render()', 'example.rhtml')
  865.   #     def initialize(items)
  866.   #       @items = items
  867.   #     end
  868.   #   end
  869.   #   print MyClass.new([10,20,30]).render()
  870.   #
  871.   # result:
  872.   #
  873.   #   <b>10</b>
  874.   #
  875.   #   <b>20</b>
  876.   #
  877.   #   <b>30</b>
  878.   #
  879.   module DefMethod
  880.     public
  881.   # define _methodname_ as instance method of current module, using ERB object or eRuby file
  882.     def def_erb_method(methodname, erb_or_fname)
  883.       if erb_or_fname.kind_of? String
  884.         fname = erb_or_fname
  885.         erb = ERB.new(File.read(fname))
  886.         erb.def_method(self, methodname, fname)
  887.       else
  888.         erb = erb_or_fname
  889.         erb.def_method(self, methodname, erb.filename || '(ERB)')
  890.       end
  891.     end
  892.     module_function :def_erb_method
  893.   end
  894. end
  895.